home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UFolderSelectView.cp < prev    next >
Encoding:
Text File  |  1994-02-20  |  12.9 KB  |  552 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UFolderSelectView.cp
  3.  
  4. #include "UFolderSelectView.h"
  5. #include "Tools.h"
  6. #include "FontTools.h"
  7. #include "FileTools.h"
  8. #include "UPrefsDatabase.h"
  9.  
  10. #include <RsrcGlobals.h>
  11.  
  12. #include <Packages.h>
  13. #include <ToolUtils.h>
  14. #include <UDialog.h>
  15. #include <Resources.h>
  16. #include <Folders.h>
  17. #include <Script.h>
  18.  
  19. #pragma segment MyViewTools
  20.  
  21. StandardFileReply gReply; // used from call-backs
  22. CStr255 gPrevSelectedName;
  23. Boolean gWasCancel, gIsDesktopFolder;
  24. CStr255 gPromptString = "";
  25. ControlHandle gGetDirButtonControlH;
  26. CRect gGetDirButtonControlRect;
  27.  
  28. void GetPathNameFromDirID(short vRefNum, long dirID, CStr255 &pathName);
  29.  
  30. // some of this code is from SCN.18.StdFilev2a3
  31.  
  32.  
  33. long GetSFCurDir() 
  34. {
  35.     return *(long*)CurDirStore;
  36. }
  37.  
  38. short GetSFVRefNum()
  39. {
  40.     return -*(short*)SFSaveDisk; // obs: contains negative of vRefNum
  41. }
  42.  
  43. void OStypetoChars(const OSType id, char *store)
  44. {
  45.     store[0] = char(id >> 24 & 255);
  46.     store[1] = char(id >> 16 & 255); 
  47.     store[2] = char(id >>  8 & 255);
  48.     store[3] = char(id       & 255);
  49.     store[4] = 0;
  50. }
  51.  
  52. void DumpReply()
  53. {
  54. #if qDebug
  55.     char store[100];
  56.     OStypetoChars(gReply.sfType, store);
  57.     CStr255 path, s;
  58.     GetPathNameFromDirID(gReply.sfFile.vRefNum, gReply.sfFile.parID, path);
  59.     fprintf(stderr, "\n");
  60.     fprintf(stderr, "Dump of gReply:\n");
  61.     fprintf(stderr, "good = %ld, replacing = %ld\n", long(gReply.sfGood), long(gReply.sfReplacing));
  62.     fprintf(stderr, "sfType = $%lx = %s\n", gReply.sfType, store);
  63.     fprintf(stderr, "SFSaveDisk = %ld, CurDirStore = %ld\n", GetSFVRefNum(), long(GetSFCurDir()));
  64.     fprintf(stderr, "sfFile/path = %ld, %ld'\n", long(gReply.sfFile.vRefNum), long(gReply.sfFile.parID));
  65.     fprintf(stderr, "sfFile/path = '%s'\n", (char*)path);
  66.     s = gReply.sfFile.name;
  67.     fprintf(stderr, "sfFile/file = '%s'\n", (char*)s);
  68.     fprintf(stderr, "flags = %ld, isFolder = %ld, isVolume = %ld\n", long(gReply.sfFlags), long(gReply.sfIsFolder), long(gReply.sfIsVolume));
  69. #endif
  70. }
  71.  
  72. void CalculateDialogPosition(short id, CPoint &where, TWindow *window)
  73. {
  74.     CPoint c = (VPoint(window->fSize.h / 2, window->fSize.v / 2) + window->fLocation).ToPoint();
  75.     Handle h = GetResource('DLOG', id);
  76.     FailNILResource(h);
  77.     CRect r = DialogTPtr(*h)->boundsRect;
  78.     CPoint halfSize ((r.right - r.left) / 2, (r.bottom - r.top) / 2);
  79.     where = c - halfSize;
  80. /*
  81. #if qDebug
  82.     fprintf(stderr, "Location of window (%ld, %ld)\n", view->fLocation[hSel], view->fLocation[vSel]);
  83.     fprintf(stderr, "Center of window: (%hd, %hd)\n", c[hSel], c[vSel]);
  84.     fprintf(stderr, "halfSize of DLOG: (%hd, %hd)\n", halfSize.h, halfSize.v);
  85.     fprintf(stderr, "where: (%hd, %hd)\n", where.h, where.v);
  86. #endif
  87. */
  88. }
  89.  
  90.  
  91. //**** FILE SELECT ************************************************************
  92. #pragma push
  93. #pragma trace off
  94. #pragma segment A5Ref
  95. pascal Boolean FileFFilter(ParmBlkPtr pb, void *yourDataPtr) // call-back!
  96. {
  97.     TFileSelectView *fsv = (TFileSelectView*) yourDataPtr;
  98.     return fsv->DontShowFileFilter(pb);
  99. }
  100. #pragma pop
  101.  
  102. #pragma segment MyViewTools
  103.  
  104. Boolean TFileSelectView::DontShowFileFilter(ParmBlkPtr pb)
  105. {
  106.     const short kFolderBit = 4; // bit set in ioFlAttrib for a folder
  107.     unsigned char attrib = pb->fileParam.ioFlAttrib;
  108.     if ( (attrib >> kFolderBit) & 1)
  109.         return false; // always show folders
  110.  
  111.     // return true means don't show file
  112.     OSType creator = pb->fileParam.ioFlFndrInfo.fdCreator;
  113.     OSType type = pb->fileParam.ioFlFndrInfo.fdType;
  114.     if (fNeededFileType == 'TEXT' && fNeededCreator == '????')
  115.     {
  116.         if (type == 'PREF' && creator == 'CSOm')
  117.             return false; // special case for Eudora Settings file (contains signature)
  118.     }
  119.     if (fNeededCreator != '????' && creator != fNeededCreator)
  120.         return true; // creator don't match: don't show it
  121.     if (fNeededFileType != '????' && type != fNeededFileType)
  122.         return true; // type don't match: don't show it
  123.     return false;
  124. }
  125.  
  126. TFileSelectView::TFileSelectView()
  127. {
  128. }
  129.  
  130.  
  131. pascal void TFileSelectView::Initialize()
  132. {
  133.     inherited::Initialize();
  134.     fButton = nil;
  135.     fPath = nil;
  136.     fGotFile = false;
  137.     fNeededFileType = 'zxcv';
  138.     fNeededCreator = '????';
  139. }
  140.  
  141. pascal void TFileSelectView::ReadFields(TStream *aStream)
  142. {
  143.     inherited::ReadFields(aStream);
  144. }
  145.  
  146. pascal void TFileSelectView::DoPostCreate(TDocument *itsDocument)
  147. {
  148.     inherited::DoPostCreate(itsDocument);
  149.     fButton = (TButton*)FindSubView(kFolderSelectButtonID);
  150.     if (!fButton)
  151.     {
  152. #if qDebug
  153.         ProgramBreak("Sub-view button not found!");
  154. #endif
  155.         Failure(0, 0);
  156.     }
  157.     fPath = (TStaticText*)FindSubView(kFolderSelectPathID);
  158.     if (!fPath)
  159.     {
  160. #if qDebug
  161.         ProgramBreak("Sub-view statictext to path not found!");
  162. #endif
  163.         Failure(0, 0);
  164.     }
  165. }
  166.  
  167. pascal void TFileSelectView::Free()
  168. {
  169.     fButton = nil; // view
  170.     fPath = nil; // view
  171.     inherited::Free();
  172. }
  173.  
  174. void TFileSelectView::SpecifyFileTypes(OSType fileType, OSType creator)
  175. {
  176.     fNeededFileType = fileType;
  177.     fNeededCreator = creator;
  178. }
  179.  
  180. Boolean TFileSelectView::DoGetFile()
  181. {
  182.     CPoint where;
  183.     SFTypeList myTypeList;
  184.         
  185.     CalculateDialogPosition(sfGetDialogID, where, GetWindow());
  186.  
  187.     CustomGetFile(FileFFilter, -1, myTypeList, gReply, sfGetDialogID, where, nil, nil, nil, nil, this);
  188.     if (!gReply.sfGood)
  189.         return false;
  190.     FInfo info;
  191.     FailOSErr(FSpGetFInfo(gReply.sfFile, info));
  192.     fSignature = info.fdCreator;
  193.     fSpec = gReply.sfFile;
  194.     fGotFile = true;
  195.     UpdatePathName();
  196.     return true;
  197. }
  198.  
  199. void TFileSelectView::UpdatePathName()
  200. {
  201.     CStr255 path;
  202.     GetPathNameFromDirID(fSpec.vRefNum, fSpec.parID, path);
  203.     CStr255 name(fSpec.name);
  204.     path += name;
  205.     fPath->Focus();
  206.     TextStyle ts = fPath->fTextStyle;
  207.     SetPortTextStyle(ts);
  208.     TruncString(short(fPath->fSize.h), path, smTruncMiddle);
  209.     fPath->SetText(path, kRedraw);
  210. }
  211.  
  212. pascal void TFileSelectView::DoEvent(EventNumber eventNumber, TEventHandler *source, TEvent *event)
  213. {
  214.     if (eventNumber == mButtonHit)
  215.         DoGetFile();
  216.     else
  217.         inherited::DoEvent(eventNumber, source, event);
  218. }
  219.  
  220. void TFileSelectView::Specify(const FSSpec &spec)
  221. {
  222.     fSpec = spec;
  223.     fGotFile = true;
  224.     UpdatePathName();
  225. }
  226.  
  227. void TFileSelectView::GetFile(FSSpec &spec)
  228. {
  229.     spec = fSpec;
  230. }
  231.  
  232. void TFileSelectView::DimState(Boolean state, Boolean redraw)
  233. {
  234.     fButton->DimState(state, redraw);
  235.     fPath->DimState(state, redraw);
  236. }
  237.  
  238. Boolean TFileSelectView::GotFile()
  239. {
  240.     return fGotFile;
  241. }
  242.  
  243. OSType TFileSelectView::GetFileSignature()
  244. {
  245.     return fSignature;
  246. }
  247.  
  248. void TFileSelectView::InitializeFromPreferences(OSType pref)
  249. {
  250.     if (!gPrefs->PrefExists(pref))
  251.         return;
  252.     FailInfo fi;
  253.     if (fi.Try())
  254.     {
  255.         FSSpec spec;
  256.         gPrefs->GetAliasPrefs(pref, spec);
  257.         Specify(spec);
  258.         fi.Success();
  259.     }
  260.     else // fail
  261.     {
  262.         // ignore currently
  263.     }    
  264. }
  265.  
  266. void TFileSelectView::StoreInPreferences(OSType pref)
  267. {
  268.     if (!fGotFile)
  269.         return;
  270.     FSSpec spec = fSpec;
  271.     gPrefs->SetAliasPrefs(pref, spec);
  272. }
  273. //**** FOLDER SELECT ************************************************************
  274. TFolderSelectView::TFolderSelectView()
  275. {
  276. }
  277.  
  278.  
  279. pascal void TFolderSelectView::Initialize()
  280. {
  281.     inherited::Initialize();
  282.     fButton = nil;
  283.     fPath = nil;
  284.     fGotFolder = false;
  285.     fPromptString = "";
  286. }
  287.  
  288. pascal void TFolderSelectView::ReadFields(TStream *aStream)
  289. {
  290.     inherited::ReadFields(aStream);
  291.     CStr255 s;
  292.     MyGetIndString(s, kAskFolderPrompt);
  293.     fPromptString = s;
  294. }
  295.  
  296. pascal void TFolderSelectView::DoPostCreate(TDocument *itsDocument)
  297. {
  298.     inherited::DoPostCreate(itsDocument);
  299.     fButton = (TButton*)FindSubView(kFolderSelectButtonID);
  300.     if (!fButton)
  301.     {
  302. #if qDebug
  303.         ProgramBreak("Sub-view button not found!");
  304. #endif
  305.         Failure(0, 0);
  306.     }
  307.     fPath = (TStaticText*)FindSubView(kFolderSelectPathID);
  308.     if (!fPath)
  309.     {
  310. #if qDebug
  311.         ProgramBreak("Sub-view statictext to path not found!");
  312. #endif
  313.         Failure(0, 0);
  314.     }
  315. }
  316.  
  317. pascal void TFolderSelectView::Free()
  318. {
  319.     fButton = nil; // view
  320.     fPath = nil; // view
  321.     inherited::Free();
  322. }
  323.  
  324. #pragma segment A5Ref
  325. #pragma push
  326. #pragma trace off
  327. void SetButtonTitle(ControlHandle ButtonHdl, CStr255 &name, const CRect &buttonRect)
  328. {
  329.     if (!ButtonHdl)
  330.         return;
  331.     gPrevSelectedName = name;
  332.     CStr255 preName, postName;
  333.     MyGetIndString(preName, kPreSelectFolderText);
  334.     MyGetIndString(postName, kPostSelectFolderText);
  335.     short width = buttonRect.GetLength(hSel) - StringWidth(preName + postName);
  336.     TruncSystemFontString(width, name, smTruncMiddle);
  337.     CStr255 s(preName);
  338.     s += name;
  339.     s += postName;
  340.     name = s;
  341.     SetCTitle(ButtonHdl, name);
  342.     ValidRect(buttonRect);
  343. }
  344. #pragma pop
  345.  
  346. #pragma segment A5Ref
  347. #pragma push
  348. #pragma trace off
  349. pascal Boolean FolderFFilter(ParmBlkPtr PB, void* /* yourDataPtr */) // call-back!
  350. { // return true means don't show file
  351.     const short kFolderBit = 4; // bit set in ioFlAttrib for a folder
  352.     unsigned char attrib = PB->fileParam.ioFlAttrib;
  353.     if ( ((attrib >> kFolderBit) & 1) == 0)
  354.         return true;
  355.     return false;
  356. }
  357. #pragma pop
  358.  
  359. #pragma segment A5Ref
  360. #pragma push
  361. #pragma trace off
  362. pascal short GetDirDlgHook(short item, DialogPtr theDialog, void* /* yourDataPtr */) // call-back!
  363. {
  364.     if (OSType(WindowPeek(theDialog)->refCon) != sfMainDialogRefCon)
  365.         return item;
  366.     CStr255 messageTitle;
  367.     CRect iRect;
  368.     Handle iHandle;
  369.     short iKind;
  370.     CStr255 selectedName;
  371.  
  372.     switch (item)
  373.     {
  374.         case sfHookFirstCall:
  375.             GetDItem(theDialog, kGetDirMessage, iKind, iHandle, iRect);
  376.             SetIText(iHandle, gPromptString);
  377. #if 1
  378.             CInfoPBRec info;
  379.             info.dirInfo.ioCompletion = nil;
  380.             info.dirInfo.ioNamePtr = StringPtr(&selectedName);
  381.             info.dirInfo.ioVRefNum = GetSFVRefNum();
  382.             info.dirInfo.ioFDirIndex = -1;
  383.             info.dirInfo.ioDrDirID = GetSFCurDir();
  384.             PBGetCatInfoSync(&info);
  385.             GetDItem(theDialog, kGetDirButton, iKind, iHandle, gGetDirButtonControlRect);
  386.             gGetDirButtonControlH = ControlHandle(iHandle);
  387.             SetButtonTitle(gGetDirButtonControlH, selectedName, gGetDirButtonControlRect);
  388.             break;
  389. #endif
  390.         case kGetDirButton:
  391.             gWasCancel = false;
  392.             return sfItemCancelButton;
  393.  
  394.         case kGetDesktopButton:
  395.             gWasCancel = false;
  396.             gIsDesktopFolder = true;
  397.             return sfItemCancelButton;
  398.         
  399.         case sfItemCancelButton:
  400.             gWasCancel = true;
  401.             return sfItemCancelButton;
  402.  
  403.         case sfHookNullEvent:
  404.             if (IsControlKeyDown())
  405.                 DumpReply();
  406. #if 1
  407.             if (gReply.sfIsFolder || gReply.sfIsVolume)
  408.                 selectedName = gReply.sfFile.name;
  409.             else
  410.             {
  411.                 CInfoPBRec info;
  412.                 info.dirInfo.ioCompletion = nil;
  413.                 info.dirInfo.ioNamePtr = StringPtr(&selectedName);
  414.                 info.dirInfo.ioVRefNum = gReply.sfFile.vRefNum;
  415.                 info.dirInfo.ioFDirIndex = -1;
  416.                 info.dirInfo.ioDrDirID = gReply.sfFile.parID;
  417.                 PBGetCatInfoSync(&info);
  418. #if qDebug & 0
  419.                 fprintf(stderr, "Non-folder/volume name: '%s'\n", (char*)selectedName);
  420. #endif
  421.             }
  422.             if (selectedName != gPrevSelectedName)
  423.                 SetButtonTitle(gGetDirButtonControlH, selectedName, gGetDirButtonControlRect);
  424.  
  425. #endif
  426.             break;
  427.  
  428.         default:
  429.             break;
  430.     }
  431.     return item;
  432. }
  433. #pragma pop
  434.  
  435. #pragma segment MyViewTools
  436. Boolean TFolderSelectView::DoGetDirectory()
  437. {
  438.     CPoint where;
  439.  
  440.     SFTypeList myTypeList;
  441.     const short kShowAllFiles = - 1;
  442.         
  443.     CalculateDialogPosition(kGetDirectoryDLOG, where, GetWindow());
  444.     gPromptString = fPromptString;
  445.     gPrevSelectedName = "";
  446.     gWasCancel = true;
  447.     gIsDesktopFolder = false;
  448.     gGetDirButtonControlH = nil;
  449.     
  450.     CustomGetFile(FolderFFilter, kShowAllFiles, myTypeList,
  451.                           gReply, kGetDirectoryDLOG, where,
  452.                           &GetDirDlgHook, nil, nil,
  453.                           nil, nil);
  454.     if (gWasCancel)
  455.         return false;
  456. #if 1
  457.     if (gIsDesktopFolder)
  458.     {
  459.         short vRefNum; long dirID;
  460.         FailOSErr(FindFolder(gReply.sfFile.vRefNum, kDesktopFolderType, kCreateFolder, vRefNum, dirID));
  461.         fVRefNum = vRefNum;
  462.         fDirID = dirID;
  463.     }
  464.     else
  465.     {
  466.         CInfoPBRec info;
  467.         info.dirInfo.ioCompletion = nil;
  468.         info.dirInfo.ioNamePtr = gReply.sfFile.name;
  469.         info.dirInfo.ioVRefNum = gReply.sfFile.vRefNum;
  470.         info.dirInfo.ioFDirIndex = 0;
  471.         info.dirInfo.ioDrDirID = gReply.sfFile.parID;
  472.         PBGetCatInfoSync(&info);
  473.         fVRefNum = gReply.sfFile.vRefNum;
  474.         fDirID = info.dirInfo.ioDrDirID;
  475.     }
  476. #else
  477.     fVRefNum = gReply.sfFile.vRefNum;
  478.     fDirID = gReply.sfFile.parID;
  479. #endif
  480.     UpdatePathName();
  481.     fGotFolder = true;
  482.     return true;
  483. }
  484.  
  485. void TFolderSelectView::UpdatePathName()
  486. {
  487.     CStr255 path;
  488.     GetPathNameFromDirID(fVRefNum, fDirID, path);
  489.     fPath->Focus();
  490.     TextStyle ts = fPath->fTextStyle;
  491.     SetPortTextStyle(ts);
  492.     TruncString(short(fPath->fSize.h), path, smTruncMiddle);
  493.     fPath->SetText(path, kRedraw);
  494. }
  495.  
  496. pascal void TFolderSelectView::DoEvent(EventNumber eventNumber, TEventHandler *source, TEvent *event)
  497. {
  498.     if (eventNumber == mButtonHit)
  499.         DoGetDirectory();
  500.     else
  501.         inherited::DoEvent(eventNumber, source, event);
  502. }
  503.  
  504. void TFolderSelectView::Specify(short vRefNum, long dirID)
  505. {
  506.     fVRefNum = vRefNum;
  507.     fDirID = dirID;
  508.     UpdatePathName();
  509.     fGotFolder = true;
  510. }
  511.  
  512. void TFolderSelectView::GetDir(short &vRefNum, long &dirID)
  513. {
  514.     vRefNum = fVRefNum;
  515.     dirID = fDirID;
  516. }
  517.  
  518. void TFolderSelectView::DimState(Boolean state, Boolean redraw)
  519. {
  520.     fButton->DimState(state, redraw);
  521.     fPath->DimState(state, redraw);
  522. }
  523.  
  524. void TFolderSelectView::InitializeFromPreferences(OSType pref)
  525. {
  526.     if (!gPrefs->PrefExists(pref))
  527.         return;
  528.     FailInfo fi;
  529.     if (fi.Try())
  530.     {
  531.         FSSpec spec;
  532.         gPrefs->GetSilentDirAliasPrefs(pref, spec);
  533.         Specify(spec.vRefNum, spec.parID);
  534.         fi.Success();
  535.     }
  536.     else // fail
  537.     {
  538.         if (fi.error)
  539.             fi.ReSignal(); // ignore cancel, open dialog anyway
  540.     }
  541. }
  542.  
  543. void TFolderSelectView::StoreInPreferences(OSType pref)
  544. {
  545.     if (!fGotFolder)
  546.         return;
  547.     FSSpec spec;
  548.     spec.vRefNum = fVRefNum;
  549.     spec.parID = fDirID;
  550.     gPrefs->SetDirAliasPrefs(pref, spec);
  551. }
  552.